package com.framework.foundation.common;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;

import com.framework.foundation.common.vo.BTResult;
import com.framework.foundation.common.vo.IResult;
import com.framework.foundation.common.vo.Result;
import com.framework.foundation.util.Reflections;
import com.framework.foundation.util.sqlxml.SqlKit;
import com.jfinal.aop.Enhancer;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.Table;
import com.jfinal.plugin.activerecord.TableMapping;

public abstract class BaseService<M extends Model<M>> {

	protected static final Log LOG = Log.getLog(BaseService.class);

	public static final BaseService me = Enhancer.enhance(BaseService.class);

	/**
	 * bootstraptable分页查询<br>
	 * 
	 * 基本参数:<br>
	 * pageNumber 第几页<br>
	 * pageSize 每页显示多少条记录<br>
	 * sortName 排序列名<br>
	 * sortOrder 排序类型<br>
	 * 
	 * @param param 请求参数
	 * @return
	 * @Author: Brin
	 * @Date: 2015年11月2日 上午10:52:11
	 */
	public BTResult<Record> paginate(Map<String, Object> param) {
		Table table = getTable();
		Page<Record> pages = Db.paginate(MapUtils.getInteger(param, "pageNumber"),
				MapUtils.getInteger(param, "pageSize"), "SELECT *",
				"FROM " + table.getName() + " WHERE deleteMark = 0 ORDER BY id DESC", new Object[0]);
		return new BTResult<Record>(pages.getTotalRow(), pages.getList());
	}

	/**
	 * 新增方法
	 * 
	 * @param user
	 * @return
	 * @Author: Brin
	 * @Date: 2015年11月10日 下午1:58:08
	 */
	public IResult<Object> save(M model) {
		try {
			if (null == model) {
				return Result.createFail(model);
			}
			return Result.create(model.save(), model);
		} catch (Exception e) {
			throw new RuntimeException("新增异常---->" + getClass().getSuperclass().getSimpleName(), e);
		}
	}

	/**
	 * 编辑方法
	 * 
	 * @param user
	 * @return
	 * @Author: Brin
	 * @Date: 2015年11月10日 下午1:58:08
	 */
	public IResult<Object> update(M model) {
		try {
			if (null == model) {
				return Result.createFail(model);
			}
			return Result.create(model.update(), model);
		} catch (Exception e) {
			throw new RuntimeException("编辑异常---->" + getClass().getSuperclass().getSimpleName(), e);
		}
	}

	/**
	 * 逻辑删除模型
	 * 
	 * @param id数组
	 * @return
	 * @Author: Brin
	 * @Date: 2015年11月10日 下午1:58:08
	 */
	public IResult<Object> logicDelete(String[] ids) {
		try {
			if (ArrayUtils.isEmpty(ids)) {
				return Result.createFail(0);
			}
			Table table = getTable();
			Object[][] paras = new Object[ids.length][1];
			for (int i = 0; i < ids.length; i++) {
				paras[i][0] = ids[i];
			}
			int[] affect = Db.batch("UPDATE " + table.getName() + " SET deleteMark = 1 WHERE id = ?", paras, 1000);
			return Result.create(affect[0] > 0, affect[0]);
		} catch (Exception e) {
			throw new RuntimeException("删除异常---->" + getClass().getSuperclass().getSimpleName(), e);
		}
	}

	/**
	 * 物理删除模型
	 * 
	 * @param id数组
	 * @return
	 * @Author: Brin
	 * @Date: 2015年11月10日 下午1:58:08
	 */
	public IResult<Object> delete(String[] ids) {
		try {
			if (ArrayUtils.isEmpty(ids)) {
				return Result.createFail();
			}
			Table table = getTable();
			Object[][] paras = new Object[ids.length][1];
			for (int i = 0; i < ids.length; i++) {
				paras[i][0] = ids[i];
			}
			int[] affect = Db.batch("DELETE FROM " + table.getName() + " WHERE id = ?", paras, 1000);
			return Result.create(affect[0] > 0, affect[0]);
		} catch (Exception e) {
			throw new RuntimeException("删除异常---->" + getClass().getSuperclass().getSimpleName(), e);
		}
	}

	/**
	 * 封装解析freemarker参数并执行查询
	 * 注意: 这里主要执行freemark解析后的动态sql语句, 其他语句直接编写不需要统一管理
	 * 
	 * @param groupNameAndsqlId
	 * @param conditions freemarker条件参数
	 * @return
	 */
	public <T> List<T> dynamicQuery(String groupNameAndsqlId, Map<String, Object> conditions) {
		String sql = SqlKit.getSqlByFreemarker(groupNameAndsqlId, conditions);
		return Db.query(sql);
	}

	/**
	 * 封装解析freemarker参数并执行查询
	 * 注意: 这里主要执行freemark解析后的动态sql语句, 其他语句直接编写不需要统一管理
	 * 
	 * @param groupNameAndsqlId
	 * @param conditions freemarker条件参数
	 * @return
	 */
	public List<Record> dynamicFind(String groupNameAndsqlId, Map<String, Object> conditions) {
		String sql = SqlKit.getSqlByFreemarker(groupNameAndsqlId, conditions);
		return Db.find(sql);
	}

	/**
	 * 封装解析freemarker参数并执行查询
	 * 注意: 这里主要执行freemark解析后的动态sql语句, 其他语句直接编写不需要统一管理
	 * 
	 * @param groupNameAndsqlId
	 * @param conditions freemarker条件参数
	 * @return
	 */
	public int dynamicUpdate(String groupNameAndsqlId, Map<String, Object> conditions) {
		String sql = SqlKit.getSqlByFreemarker(groupNameAndsqlId, conditions);
		return Db.update(sql);
	}

	/**
	 * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
	 * 
	 * @return
	 * @Author: Brin
	 * @Date: 2015年12月9日 上午11:25:02
	 */
	private Table getTable() {
		// 因为使用了cglib代理所以这里需要获取当前实际类的父级类对象才可以
		Class<Model> clazz = Reflections.getClassGenricType(getClass().getSuperclass());
		return TableMapping.me().getTable(clazz);
	}
}
